package com.htthorizon.model.controller;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.cloudapi.sdk.model.ApiResponse;
import com.alibaba.cloudapi.sdk.model.HttpClientBuilderParams;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONObject;
import com.htthorizon.common.core.constant.Constants;
import com.htthorizon.common.core.domain.R;
import com.htthorizon.common.core.utils.StringUtils;
import com.htthorizon.model.domain.ModelSource;
import com.htthorizon.model.response.MetaDataDto;
import com.htthorizon.model.response.MetaInfoDto;
import com.htthorizon.model.response.TestDto;
import com.htthorizon.model.service.IModelSourceService;
import com.htthorizon.system.api.model.ModelInfoReq;
import com.htthorizon.util.HttpRequestUtils;
import com.htthorizon.util.SDKGetAPIUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import com.htthorizon.common.log.annotation.Log;
import com.htthorizon.common.log.enums.BusinessType;
import com.htthorizon.common.security.annotation.RequiresPermissions;
import com.htthorizon.model.domain.ModelMeta;
import com.htthorizon.model.service.IModelMetaService;
import com.htthorizon.common.core.web.controller.BaseController;
import com.htthorizon.common.core.web.domain.AjaxResult;
import com.htthorizon.common.core.utils.poi.ExcelUtil;
import com.htthorizon.common.core.web.page.TableDataInfo;

/**
 * 模型的元数据信息Controller
 *
 * @author mark
 * @date 2023-11-16
 */
@RestController
@RefreshScope
@RequestMapping("/model/meta")
@Slf4j
public class ModelMetaController extends BaseController
{
    @Autowired
    private IModelMetaService modelMetaService;

    @Autowired
    private IModelSourceService modelSourceService;

    @Autowired
    private SDKGetAPIUtil sdkGetAPIUtil;

    @Value("${meta.url}")
    private String META_URL;

    @Value("${meta.AppKey}")
    private String META_APPKEY;

    @Value("${meta.AppCode}")
    private String META_APPCODE;

    @Value("${meta.AppSecre}")
    private String META_APPSECRE;

    @Value("${meta.path}")
    private String path;

    /**
     * 查询模型的元数据信息列表
     */
    @GetMapping("/list")
    @Log(title = "模型管理/模型元信息", businessType = BusinessType.QUERY)
    public TableDataInfo list(ModelMeta modelMeta)
    {
        List<ModelMeta> list = modelMetaService.selectModelMetaList(modelMeta);
        return getDataTable(list);
    }

    /**
     * 导出模型的元数据信息列表
     */
    @Log(title = "模型管理/模型的元数据信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ModelMeta modelMeta)
    {
        List<ModelMeta> list = modelMetaService.selectModelMetaList(modelMeta);
        ExcelUtil<ModelMeta> util = new ExcelUtil<ModelMeta>(ModelMeta.class);
        util.exportExcel(response, list, "模型的元数据信息数据");
    }

    /**
     * 保存元数据信息
     * @param modelInfo
     * @return
     */
    @PostMapping("/save")
    @Log(title = "模型管理/模型元信息", businessType = BusinessType.INSERT)
    public R<Boolean> saveMeta(@RequestBody ModelInfoReq modelInfo){
//        if(StringUtils.isEmpty(META_URL)){
//            return R.fail("请求元数据接口地址为空！");
//        }
//        Map<String,Object> paramsMap = new HashMap<>();
//        if(StringUtils.isNotEmpty(META_APPKEY)){
//            paramsMap.put("AppKey",META_APPKEY);
//        }
//        if(StringUtils.isNotEmpty(META_APPSECRE)){
//            paramsMap.put("AppCode",META_APPSECRE);
//        }
//        if(StringUtils.isNotEmpty(META_APPCODE)){
//            paramsMap.put("AppSecret",META_APPCODE);
//        }
//        ModelSource modelSource = this.modelSourceService.selectModelSourceById(modelInfo.getSourceId());
//        if(modelSource==null){
//            return R.fail("数据源为空！");
//        }
//        if(StringUtils.isEmpty(modelSource.getSourceTable())){
//            return R.fail("数据源对应的表名为空！");
//        }
//        paramsMap.put("model_tb",modelSource.getSourceTable());
//        //测试数据
//        HttpClientBuilderParams httpParam = new HttpClientBuilderParams();
//        httpParam.setAppKey(META_APPKEY);
//        httpParam.setAppSecret(META_APPSECRE);
//        sdkGetAPIUtil.init(httpParam);
//        ApiResponse metaDataByTb = sdkGetAPIUtil.getMetaDataByTb(path, modelSource.getSourceTable());
//        String result=null;
//        if (metaDataByTb.getCode()==200){
//            result= new String(metaDataByTb.getBody(), StandardCharsets.UTF_8) ;
//        }
//        log.info("result : {}" , result);
//
////        ajax.put("data", TestDto.getMetaData());
//
//        //保存元数据
////        String result = HttpRequestUtils.request(Constants.REQUEST_GET, META_URL, paramsMap);
//        if(StringUtils.isNotEmpty(result)){
//            Optional<MetaInfoDto> metaInfoDtoOpt = null;
//            try {
//                JSONObject jsonObject =  JSON.parseObject(result);
//                metaInfoDtoOpt = Optional.ofNullable(JSONObject.parseObject(jsonObject.getString("data"), MetaInfoDto.class));
//            }catch (JSONException e){
//                return R.fail("获取远程模型元数据json格式异常");
//            }
//            if(metaInfoDtoOpt.isPresent()) {
//                MetaInfoDto metaInfoDto = metaInfoDtoOpt.get();
//                List<MetaDataDto> metaDataDtoList = metaInfoDto.getRows();
//                if(CollectionUtils.isEmpty(metaDataDtoList)){
//                    return R.fail("元数据列表为空！");
//                }
//                this.modelMetaService.saveModelMeta(modelInfo ,metaDataDtoList);
//            }else {
//                return R.fail("获取远程元数据json格式异常");
//            }
//        }else{
//            return R.fail("获取远程元数据异常");
//        }
        return R.ok();
    }


    /**
     * 远程获取元数据列表
     */
    @GetMapping("/remote")
    public AjaxResult remote(@RequestParam Long sourceId) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
        if(StringUtils.isEmpty(META_URL)){
            return error("请求元数据接口地址为空！");
        }
        Map<String,Object> paramsMap = new HashMap<>();
        if(StringUtils.isNotEmpty(META_APPKEY)){
            paramsMap.put("AppKey",META_APPKEY);
        }
        if(StringUtils.isNotEmpty(META_APPSECRE)){
            paramsMap.put("AppCode",META_APPSECRE);
        }
        if(StringUtils.isNotEmpty(META_APPCODE)){
            paramsMap.put("AppSecret",META_APPCODE);
        }
        ModelSource modelSource = this.modelSourceService.selectModelSourceById(sourceId);
        if(modelSource==null){
            return error("数据源为空！");
        }
        if(StringUtils.isEmpty(modelSource.getSourceTable())){
            return error("数据源对应的表名为空！");
        }
        paramsMap.put("model_tb",modelSource.getSourceTable());
        AjaxResult ajax = AjaxResult.success();

        HttpClientBuilderParams httpParam = new HttpClientBuilderParams();
        httpParam.setAppKey(META_APPKEY);
        httpParam.setAppSecret(META_APPSECRE);
        sdkGetAPIUtil.init(httpParam);
        ApiResponse metaDataByTb = sdkGetAPIUtil.getMetaDataByTb(path, modelSource.getSourceTable());
        String result=null;
        if (metaDataByTb.getCode()==200){
            result= new String(metaDataByTb.getBody(), StandardCharsets.UTF_8) ;
        }
        log.info("result : {}" , result);


        ajax.put("data", result);

        if(StringUtils.isNotEmpty(result)){
            Optional<MetaInfoDto> metaInfoDtoOpt = null;
            try {
                JSONObject jsonObject =  JSON.parseObject(result);
                metaInfoDtoOpt = Optional.ofNullable(JSONObject.parseObject(jsonObject.getString("data"), MetaInfoDto.class));
            }catch (JSONException e){
                return error("获取远程模型元数据json格式异常");
            }
            if(metaInfoDtoOpt.isPresent()) {
                MetaInfoDto metaInfoDto = metaInfoDtoOpt.get();
                List<MetaDataDto> rows = metaInfoDto.getRows();
                if(CollectionUtils.isEmpty(rows)){
                    return success("元数据列表为空！");
                }
                ModelMeta modelMeta = null;
                List<ModelMeta> modelMetaList = new ArrayList<>(rows.size());
                for (int i=0; i<rows.size(); i++){
                    MetaDataDto dto = rows.get(i);
                    modelMeta = new ModelMeta();
                    modelMeta.setMetaFieldSort(i+1);
                    modelMeta.setMetaFieldName(dto.getName());
                    modelMeta.setMetaFieldRemark(dto.getCol_comment());
                    modelMeta.setMetaFieldType(dto.getType());
                    modelMeta.setModelName(dto.getModel_tb());
                    modelMetaList.add(modelMeta);
                }
                ajax.put("modelMetaList", modelMetaList);
            }
        }else{
            return AjaxResult.error("获取远程元数据异常");
        }
        return ajax;
    }

    /**
     * 获取模型的元数据信息详细信息
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(modelMetaService.selectModelMetaById(id));
    }


}
